<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript 类型检测</title>
    <style>
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            max-width: 800px;
            margin: 0 auto;
            background-color: #fff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        h1 { text-align: center; }
        table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th { background-color: #f2f2f2; }
        code { 
            background-color: #f8f8f8;
            padding: 2px 4px;
            border-radius: 3px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>JavaScript 类型检测方法</h1>
        
        <table>
            <thead>
                <tr>
                    <th>值</th>
                    <th>typeof</th>
                    <th>instanceof</th>
                    <th>constructor</th>
                    <th>Object.prototype.toString</th>
                </tr>
            </thead>
            <tbody id="results">
                <!-- 结果将通过JavaScript填充 -->
            </tbody>
        </table>
    </div>

    <script>
        // 测试数据
        const testData = [
            { name: "数字", value: 42 },
            { name: "字符串", value: "Hello" },
            { name: "布尔值", value: true },
            { name: "undefined", value: undefined },
            { name: "null", value: null },
            { name: "对象", value: {} },
            { name: "数组", value: [1, 2, 3] },
            { name: "函数", value: function() {} },
            { name: "日期", value: new Date() }
        ];

        const resultsTable = document.getElementById("results");
        
        // 检测每个值的类型
        testData.forEach(item => {
            const row = document.createElement("tr");
            
            // 值名称
            const nameCell = document.createElement("td");
            nameCell.textContent = item.name;
            row.appendChild(nameCell);
            
            // typeof
            const typeofCell = document.createElement("td");
            typeofCell.textContent = typeof item.value;
            row.appendChild(typeofCell);
            
            // instanceof
            const instanceofCell = document.createElement("td");
            try {
                if (item.value === null || item.value === undefined) {
                    instanceofCell.textContent = "N/A";
                } else {
                    let result = [];
                    if (item.value instanceof Object) result.push("Object");
                    if (item.value instanceof Array) result.push("Array");
                    if (item.value instanceof Function) result.push("Function");
                    if (item.value instanceof Date) result.push("Date");
                    
                    instanceofCell.textContent = result.join(", ") || "无匹配";
                }
            } catch (e) {
                instanceofCell.textContent = "错误";
            }
            row.appendChild(instanceofCell);
            
            // constructor
            const constructorCell = document.createElement("td");
            try {
                if (item.value === null || item.value === undefined) {
                    constructorCell.textContent = "N/A";
                } else {
                    constructorCell.textContent = item.value.constructor.name;
                }
            } catch (e) {
                constructorCell.textContent = "错误";
            }
            row.appendChild(constructorCell);
            
            // Object.prototype.toString
            const toStringCell = document.createElement("td");
            toStringCell.textContent = Object.prototype.toString.call(item.value);
            row.appendChild(toStringCell);
            
            resultsTable.appendChild(row);
        });

        // 添加自定义类型示例
        function addCustomExample() {
            class Person {
                constructor(name) {
                    this.name = name;
                }
            }
            
            const person = new Person("张三");
            
            const row = document.createElement("tr");
            
            const nameCell = document.createElement("td");
            nameCell.textContent = "自定义类 (Person)";
            row.appendChild(nameCell);
            
            const typeofCell = document.createElement("td");
            typeofCell.textContent = typeof person;
            row.appendChild(typeofCell);
            
            const instanceofCell = document.createElement("td");
            instanceofCell.textContent = `Person: ${person instanceof Person}, Object: ${person instanceof Object}`;
            row.appendChild(instanceofCell);
            
            const constructorCell = document.createElement("td");
            constructorCell.textContent = person.constructor.name;
            row.appendChild(constructorCell);
            
            const toStringCell = document.createElement("td");
            toStringCell.textContent = Object.prototype.toString.call(person);
            row.appendChild(toStringCell);
            
            resultsTable.appendChild(row);
        }
        
        addCustomExample();
    </script>
</body>
</html>